#include <QtGui>
#include "QtFormulaBar.h"


QtFormulaBar::QtFormulaBar(BusiCoord* pBusiCoord, QtStraStrategyInfo* barinfo, QWidget *parent): QWidget(parent)
{
	m_barinfo = barinfo;
	

	setBackgroundRole(QPalette::Dark);
	setAutoFillBackground(true);
	//setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	//setFocusPolicy(Qt::StrongFocus);

	

	//pBusiCoord
	m_pBusiCoord = pBusiCoord;


	{
		int x = BusiCoord::LeftMargin - geometry().x();

		int y = TopMargin;

		int width = m_pBusiCoord->GetBusiRect()->width();

		int h = height() - TopMargin - BottomMargin;


		m_pBusiRect = new QRect(x, y, width, h);
	}





	//cursorshown
	m_eMouseShow = NotShow;
		

	//Draw elements on buffers

	RefreshBuffer();



}



void QtFormulaBar::RefreshBuffer()
{
	UpdateBarInfoWidget(true);

	pixmap = QPixmap(size());
	pixmap.fill(this, 0, 0);

	QPainter painter(&pixmap);
	painter.initFrom(this);
	bool ret1 = DrawGrid(&painter);
	bool ret2 = DrawBars(&painter);
	if (ret1 && ret2)
		update();


}


bool QtFormulaBar::minAndmaxY(int minXIndex, int maxXIndex, double& minY, double& maxY)
{
	BarData* pData = NULL;


	if (m_pBusiCoord->GetBarData(minXIndex, pData))
	{
		minY = pData->low;
		maxY = pData->high;

		for (int i = minXIndex; i <= maxXIndex; i++)
		{

			if (m_pBusiCoord->GetBarData(i, pData))
			{
				double low = pData->low;
				double high = pData->high;

				if (low < minY)
				{
					minY = low;
				}

				if (high > maxY)
				{
					maxY = high;
				}
			}
			else
				return false;
		
		}

	}
	else
		return false;



	return true;
}



bool QtFormulaBar::DrawGrid(QPainter *painter)
{

	int minXIndex; int maxXIndex; 
	if (false == m_pBusiCoord->BusiCoordIndex(minXIndex, maxXIndex))
		return false;

	ZoomSeetings* pzoom = m_pBusiCoord->GetZoom();
	int shift = pzoom->barwidth / 2;
	int distance = pzoom->distance;


	




	QPen quiteDark = palette().dark().color().light();
	QPen light = palette().light().color();






	int num = 0;

	for (int index = minXIndex; index <= maxXIndex; ++index, num++)
	{
		if (0 == num % 5)
		{
			BarData* pData = NULL;

			if (m_pBusiCoord->GetBarData(index, pData))
			{

				int x = m_pBusiRect->left() + shift + distance * num;

				//should be changed into related time
				QString strlable =  QString::number(pData->starttime.wHour);
				strlable += ":";
				strlable += QString::number(pData->starttime.wMinute);


				painter->setPen(light);
				painter->drawLine(x, m_pBusiRect->bottom(), x, m_pBusiRect->bottom() + 5);
				painter->drawText(x - m_pBusiRect->left(), m_pBusiRect->bottom() + 5, m_pBusiRect->left() * 2, 20,
					Qt::AlignHCenter | Qt::AlignTop,
					strlable);

			}
						
		}


	}



	double minY; double maxY; int numYGridArea = 4;


	if (minAndmaxY(minXIndex, maxXIndex, minY, maxY))
	{

		for (int j = 0; j <= numYGridArea; ++j) 
		{
			int y = m_pBusiRect->top() + (j * (m_pBusiRect->height())	/ numYGridArea) - 1;

			if (j == 0)
				y++;
			

			double label = minY + (j * (maxY - minY) / numYGridArea);


			painter->setPen(quiteDark);
			painter->drawLine(m_pBusiRect->left(), y, m_pBusiRect->right(), y);
			painter->setPen(light);
			painter->drawLine(m_pBusiRect->left() - 5, y, m_pBusiRect->left(), y);
			painter->drawText(0, y - 10, m_pBusiRect->left() - 5, 20,
				Qt::AlignRight | Qt::AlignVCenter,
				QString::number(label));
		}


		painter->setPen(quiteDark);

		painter->drawRect(m_pBusiRect->adjusted(0, 0, -1, -1));
	}
	

	
	


	

	return true;
}

bool QtFormulaBar::DrawBars(QPainter *painter)
{
	int minXIndex; int maxXIndex; 
	if (false == m_pBusiCoord->BusiCoordIndex(minXIndex, maxXIndex))
		return false;


	ZoomSeetings* pzoom = m_pBusiCoord->GetZoom();
	int shift = pzoom->barwidth / 2;
	int distance = pzoom->distance;
	int barwidth = pzoom->barwidth;

	

	double minY; double maxY; 
	
	if (minAndmaxY(minXIndex, maxXIndex, minY, maxY))
	{
		int num = 0;

		for (int index = minXIndex; index <= maxXIndex; ++index, num++)
		{
			BarData* pData = NULL;

			if (m_pBusiCoord->GetBarData(index, pData))
			{
				int x = m_pBusiRect->left() + distance * num;


				double dy = (maxY - minY) / (m_pBusiRect->height());


				int y = m_pBusiRect->top() + (maxY - pData->open) / dy;


				int width = barwidth;

				int height =  -(pData->close - pData->open) / dy;
				if (0 == height)
					height++;
				


				if (height < 0)
				{
					painter->setPen(Qt::NoPen);
					painter->setBrush(QBrush(Qt::red, Qt::SolidPattern));
				}
				else
				{
					painter->setPen(Qt::NoPen);
					painter->setBrush(QBrush(Qt::green, Qt::SolidPattern));
				}



				painter->drawRect(x, y, width, height);




				int line_x1 = x + shift;
				int line_x2 = x + shift;

				int line_y1 = m_pBusiRect->top() + (maxY - pData->high) / dy;
				int line_y2 = m_pBusiRect->top() + (maxY - pData->low) / dy;



				if (height < 0)
				{
					painter->setPen(QPen(Qt::red));
				}
				else
				{
					painter->setPen(QPen(Qt::green));
				}

				painter->drawLine(line_x1, line_y1, line_x2, line_y2);



			}


		}
	}


	return true;
}
//
////Scroll won't cause not shown bar like resizeORzoom
////
//void QtFormulaBar::Scroll(int dx)
//{
//	//if (m_pBusiCoord->Scroll(dx))
//	{
//		RefreshBuffer();
//	}
//}
//
////
////
//void QtFormulaBar::Zoom(ZoomSeetings& zoomset)
//{
//	m_zoomset = &zoomset;
//
//	RefreshBuffer();
//
//}




void QtFormulaBar::paintEvent(QPaintEvent * /* event */)
{
	QStylePainter painter(this);



	painter.drawPixmap(0, 0, pixmap);




	if (CursorShow == m_eMouseShow)
	{
		QPen quiteDark = palette().dark().color().light();
		painter.setPen(quiteDark);



		painter.drawLine(m_pBusiRect->left(), m_cursorPoint.y(), m_pBusiRect->left() + m_pBusiRect->width(), m_cursorPoint.y());
		painter.drawLine(m_cursorPoint.x(), m_pBusiRect->top(), m_cursorPoint.x(), m_pBusiRect->top() + m_pBusiRect->height());


	}
	else if (VerticalShow == m_eMouseShow)
	{
		QPen quiteDark = palette().dark().color().light();
		painter.setPen(quiteDark);

		painter.drawLine(m_cursorPoint.x(), m_pBusiRect->top(), m_cursorPoint.x(), m_pBusiRect->top() + m_pBusiRect->height());
	}

}
//
void QtFormulaBar::resizeEvent(QResizeEvent * /* event */)
{
	{
		int x = BusiCoord::LeftMargin - geometry().x();

		int y = TopMargin;

		int width = m_pBusiCoord->GetBusiRect()->width();

		int h = height() - TopMargin - BottomMargin;


		m_pBusiRect->setRect(x, y, width, h);
	}


	RefreshBuffer();
}

//void QtFormulaBar::mouseReleaseEvent(QMouseEvent *event)
//{
//	if ((event->button() == Qt::LeftButton) && m_bCursorShown) 
//	{
//		m_bCursorShown = false;
//
//
//		//printf("[mouseReleaseEvent] b4 reset\n");
//		update(m_rect.left(), m_cursorPoint.y(), m_rect.width(), 1);
//		update(m_cursorPoint.x(), m_rect.top(), 1, m_rect.height());
//
//		unsetCursor();
//	}
//}
//
void QtFormulaBar::keyPressEvent(QKeyEvent *event)
{
	QWidget::keyPressEvent(event);
}
//

void QtFormulaBar::MousePress(QPoint& point)
{

	//convert parent coordinate into widget coordinate in this widget;
	m_cursorPoint = QPoint(point.x() - geometry().x(), point.y() - geometry().y());

	
	if (m_pBusiRect->contains(m_cursorPoint)) 
	{
		m_eMouseShow = CursorShow;
		
		//printf("[QtFormulaBar::mousePressEvent] x:%d, y:%d\n", m_cursorPoint.x(), m_cursorPoint.y());


		update(m_pBusiRect->left(), m_cursorPoint.y(), m_pBusiRect->width(), 1);
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());



		setCursor(Qt::CrossCursor);
	}
	else
	{
		m_eMouseShow = VerticalShow;

	
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());

	}

	UpdateBarInfoWidget(true);

}

void QtFormulaBar::MouseMove(QPoint& point)
{
	if (CursorShow == m_eMouseShow)
	{
		update(m_pBusiRect->left(), m_cursorPoint.y(), m_pBusiRect->width(), 1);
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());
	}
	else if (VerticalShow == m_eMouseShow)
	{
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());
	}
	else
		return;


	//convert parent coordinate into widget coordinate in this widget;
	m_cursorPoint = QPoint(point.x() - geometry().x(), point.y() - geometry().y());
	
	if (m_pBusiRect->contains(m_cursorPoint))
	{
		
		m_eMouseShow = CursorShow;

		update(m_pBusiRect->left(), m_cursorPoint.y(), m_pBusiRect->width(), 1);
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());
		
	}
	else
	{
		m_eMouseShow = VerticalShow;

		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());
	}


	UpdateBarInfoWidget(true);

}


void QtFormulaBar::MouseRelease(QPoint& point)
{
	if (CursorShow == m_eMouseShow)
	{

		m_eMouseShow = NotShow;

		update(m_pBusiRect->left(), m_cursorPoint.y(), m_pBusiRect->width(), 1);
		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());

		
		unsetCursor();
	}
	else if (VerticalShow == m_eMouseShow)
	{
		m_eMouseShow = NotShow;

		update(m_cursorPoint.x(), m_pBusiRect->top(), 1, m_pBusiRect->height());
	}

	UpdateBarInfoWidget(false);

}


void QtFormulaBar::UpdateBarInfoWidget(bool bupdate)
{
	if (m_barinfo)
	{
		if (bupdate)
		{
			int index = m_pBusiCoord->GetCursorIndex();



			BarData* pData = NULL;

			if (m_pBusiCoord->GetBarData(index, pData))
			{
				//const BarData& showbar = m_pDatas->at(index);

				m_barinfo->ShowInfo(*pData);
			}



			
		} 
		else
		{
			m_barinfo->ClearInfo();

		}
	}

	
	

	
}